
#!/usr/bin/python
# -*- coding: UTF-8 -*-

from datetime import datetime
from marshmallow_sqlalchemy import fields
from config import db, ma

# Person experimenter
class Person(db.Model):
    __tablename__ = "person"
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(32), unique = True)
    duty = db.Column(db.String(32))  # Teacher or Student
    role = db.Column(db.String(32))  # user or admin

class PersonSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Person
        load_instance = True
        sqla_session = db.session

person_schema = PersonSchema()
people_schema = PersonSchema(many = True)

# US probe
class Probe(db.Model):
    __tablename__ = "probe"
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(32), unique = True)
    Nelements = db.Column(db.Integer)  # number of elements in the transducer array
    fc = db.Column(db.Float) # center frequency (in Hz)
    pitch = db.Column(db.Float) # element pitch (in m)
    kerf = db.Column(db.Float)  # element width (in m)
    width = db.Column(db.Float) # kerf width (in m)
    bandwidth = db.Column(db.Float) # 6-dB pulse-echo fractional bandwidth (in %)
    radius = db.Column(db.Float) # radius of curvature (in m, Inf for a linear array)
    focus = db.Column(db.Float)  # elevation focus (in m)
    height = db.Column(db.Float) # element height (in m)

class ProbeSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Probe
        load_instance = True
        sqla_session = db.session

probe_schema = ProbeSchema()
probes_schema = ProbeSchema(many = True)

# subject
class Subject(db.Model):
    __tablename__ = "subject"
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(32), unique = True)
    size = db.Column(db.String(32))
    description = db.Column(db.String(64))

class SubjectSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Subject
        load_instance = True
        sqla_session = db.session

subject_schema = SubjectSchema()
subjects_schema = SubjectSchema(many = True)

# 点击一次采集按钮产生一条Acquisition记录。
class Acquisition(db.Model):
    __tablename__ = "acquisition"
    id = db.Column(db.Integer, primary_key = True)
    experiment_id = db.Column(db.Integer, db.ForeignKey("experiment.id"))
    acquisition_method = db.Column(db.String(64))
    trigger_mode = db.Column(db.Integer)
    sampling_frequency = db.Column(db.Float)  # sampling frequency MHz
    laser_wavelength = db.Column(db.Integer) # nm
    laser_energy = db.Column(db.Float) #us
    #trigger_mode = db.Column(db.String(32))
    sampling_num = db.Column(db.Integer)  # Number of Samples (40Msps Samples)
    tx2rx_delay = db.Column(db.Float)   # TX2RX_Delay, Unit: us
    trigger_num = db.Column(db.Integer) # number of external trigger (laser transmission)
    trigger_period = db.Column(db.Float) # ms 
    trigger_delay = db.Column(db.Float) #Trigger in term of us
    line_number = db.Column(db.Integer) # Constant, Number of Transimitt Line in Each External Period
    pulse_width = db.Column(db.Integer) #ns
    pulse_pattern = db.Column(db.String(64)) #
    pulse_repeat_num = db.Column(db.Integer) #
    acq_pa_LNA = db.Column(db.Float) #dB
    acq_pa_PGA = db.Column(db.Float)  #dB
    acq_pa_Attenuation = db.Column(db.Float) #dB
    acq_us_LNA = db.Column(db.Float) #dB
    acq_us_PGA = db.Column(db.Float) #dB
    acq_us_Attenuation = db.Column(db.Float) #dB
    acq_voltage = db.Column(db.Float)  # mv
    acq_data_path = db.Column(db.String(512))   # 采集数据路径，下有多个采集数据文件
    timestamp = db.Column(db.DateTime)  #aquisition time


class AcquisitionSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Acquisition
        load_instance = True
        sqla_session = db.session
        include_fk = True

acquisition_schema = AcquisitionSchema()
acquisitions_schema = AcquisitionSchema(many = True)

# one experiment is composed of one or more acquisitions。实验人，实验对象，使用的探头，如果发生变化算一次新实验开始。
class Experiment(db.Model):
    __tablename__ = "experiment"
    id = db.Column(db.Integer, primary_key = True)
    person_name = db.Column(db.String(32), db.ForeignKey("person.name"))
    subject_name = db.Column(db.String(32), db.ForeignKey("subject.name"))
    probe_name = db.Column(db.String(32), db.ForeignKey("probe.name"))
    timestamp = db.Column(db.DateTime)
    remark = db.Column(db.String(128))
    exp_data_path = db.Column(db.String(256))  # 实验数据路径，下有多个采集数据路径
    acquisitions = db.relationship(
        "Acquisition",
        backref="experiment",
        cascade="all,delete,delete-orphan",
        single_parent=True,
        order_by="desc(Acquisition.timestamp)"
    )

class ExperimentSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Experiment
        load_instance = True
        sqla_session = db.session
        include_fk = True
        include_relationships = True
    
    experiments = fields.Nested(AcquisitionSchema, many=True)

experiment_schema = ExperimentSchema()
experiments_schema = ExperimentSchema(many = True)


if __name__ == "__main__":
    pass